/**
 *  Copyright (C) 2023 - Fake Inc.
 *
 *  All Rights Reserved.

*/

#ifndef INNO_LIDAR_LOG_CPP_H_
#define INNO_LIDAR_LOG_CPP_H_
#include <cstdint>
#include <string>
#include <utility>

/*
NOTE: The log macros below should be considered for exemption from MISRA inspection constraints as needed.
Otherwise, printing logs with file, function, and line information might be less convenient.

#ifndef INNO_LOG_MACROS_H
#define INNO_LOG_MACROS_H

#define INNO_LOG_DEBUG(...) \
  Fake::inno_log(Fake::InnoLogLevel::INNOLOG_LEVEL_DEBUG, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)

#define INNO_LOG_INFO(...) \
  Fake::inno_log(Fake::InnoLogLevel::INNOLOG_LEVEL_INFO, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)

#define INNO_LOG_WARN(...) \
  Fake::inno_log(Fake::InnoLogLevel::INNOLOG_LEVEL_WARN, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)

#define INNO_LOG_ERROR(...) \
  Fake::inno_log(Fake::InnoLogLevel::INNOLOG_LEVEL_ERROR, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__)
#endif  // INNO_LOG_MACROS_H
*/
namespace Fake {

enum class InnoLogLevel : int32_t {
  INNOLOG_LEVEL_TRACE = 0,
  INNOLOG_LEVEL_DEBUG = 1,
  INNOLOG_LEVEL_INFO = 2,
  INNOLOG_LEVEL_WARN = 3,
  INNOLOG_LEVEL_ERROR = 4,
  INNOLOG_LEVEL_CRITICAL = 5,
  INNOLOG_LEVEL_OFF = 6
};

void init_logger();
void inno_spd_log(const std::string& log_file, const std::string& log_func, int32_t log_line, InnoLogLevel log_lv,
                  const std::string& log_msg);

static constexpr uint32_t kLogBufferSize{1024};

template <typename... ARGS_TYPE>
void inno_log(InnoLogLevel log_lev, const std::string& log_file, const std::string& log_func, int32_t log_line,
              const std::string& fmt_str, ARGS_TYPE&&... fmt_args) {
  std::string tmp_buf(kLogBufferSize, '\0');
  int32_t sp_res{0};

  sp_res = std::snprintf(&tmp_buf[0], tmp_buf.size(), fmt_str.c_str(), std::forward<ARGS_TYPE>(fmt_args)...);
  if (sp_res >= 0) {
    inno_spd_log(log_file, log_func, log_line, log_lev, tmp_buf);
  }
}

extern "C" {
typedef void (*InnoLogCallback)(const int8_t* const log_file, const int8_t* log_func, int32_t log_line, int32_t log_lv,
                                const int8_t* log_msg);

void register_callback(InnoLogCallback log_cb);
void start_c_module();
}

}  // namespace Fake

#endif


